/*  
    Copyright 2010 Mike Eheler <mike.eheler@gmail.com>

    This file is part of Four Falling Blocks Puzzle Game.

    Four Falling Blocks Puzzle Game is free software: you can
	redistribute it and/or modify it under the terms of the GNU General
	Public License as published by the Free Software Foundation, either
	version 3 of the License, or (at your option) any later version.

    Four Falling Blocks Puzzle Game is distributed in the hope that it
	will be useful, but WITHOUT ANY WARRANTY; without even the implied
	warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
	See the GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Four Falling Blocks Puzzle Game.
	
	If not, see <http://www.gnu.org/licenses/>.
*/

#pragma once

#include "types.h"

class Piece
{
public:
	Piece();
	Piece( Piece const & );
	virtual ~Piece();

	uint8_t const * shape() const;

	virtual uint8_t type() const = 0;
	virtual void rotateLeft();
	virtual void rotateRight();
	
	virtual bool rotates() const;

	Piece & operator=( Piece const & );
	bool operator==( Piece const & );

protected:
	uint8_t mShape[4][4];
};

class PieceI : public Piece
{
public:
	PieceI();
	virtual uint8_t type() const;
	virtual void rotateLeft();
	virtual void rotateRight();
};

class PieceJ : public Piece
{
public:
	PieceJ();
	virtual uint8_t type() const;
};

class PieceL : public PieceJ
{
public:
	PieceL();
	virtual uint8_t type() const;
};

class PieceO : public Piece
{
public:
	PieceO();
	virtual uint8_t type() const;
	virtual bool rotates() const;
};

class PieceS : public Piece
{
public:
	PieceS();
	virtual uint8_t type() const;
	virtual void rotateLeft();
	virtual void rotateRight();
};

class PieceT : public Piece
{
public:
	PieceT();
	virtual uint8_t type() const;
};

class PieceZ : public Piece
{
public:
	PieceZ();
	virtual uint8_t type() const;
	virtual void rotateLeft();
	virtual void rotateRight();
};

// INLINE //
inline uint8_t const * Piece::shape() const { return &mShape[0][0]; }
inline bool Piece::rotates() const { return true; }
inline bool PieceO::rotates() const { return false; }
inline void PieceI::rotateRight() { rotateLeft(); }

inline uint8_t PieceI::type() const { return 0; }
inline uint8_t PieceJ::type() const { return 1; }
inline uint8_t PieceL::type() const { return 2; }
inline uint8_t PieceO::type() const { return 3; }
inline uint8_t PieceS::type() const { return 4; }
inline uint8_t PieceT::type() const { return 5; }
inline uint8_t PieceZ::type() const { return 6; }
